package com.bgds.sys.module.serviceimpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bgds.sys.common.constant.BizConstant;
import com.bgds.sys.module.entity.DeviceDynamicAttr;
import com.bgds.sys.module.entity.dto.TopAndLowDto;
import com.bgds.sys.module.mapper.DeviceDynamicAttrMapper;
import com.bgds.sys.module.service.IDeviceDynamicAttrService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lj
 * @since 2020-01-06
 */
@Service
@Slf4j
public class IDeviceDynamicAttrServiceImpl extends ServiceImpl<DeviceDynamicAttrMapper, DeviceDynamicAttr> implements IDeviceDynamicAttrService {
    @Autowired
    private DeviceDynamicAttrMapper deviceDynamicAttrMapper;


    @Override
    public List<DeviceDynamicAttr> listByDeviceCode(String deviceCode, String filterCode) {
        return deviceDynamicAttrMapper.listByDeviceCode(deviceCode, filterCode);
    }

    @Override
    public List<DeviceDynamicAttr> listByAlarmFlag() {
        QueryWrapper<DeviceDynamicAttr> wrapper = new QueryWrapper();
        wrapper.eq("alarm_flag", true);
        wrapper.eq("is_del", 0);
        wrapper.notLike("name","给定");
        wrapper.notLike("name","额定");
        List<DeviceDynamicAttr> alarmAttrs = deviceDynamicAttrMapper.selectList(wrapper);
        return alarmAttrs;
    }

    @Override
    public Boolean addOrUpdate(DeviceDynamicAttr attr) {
        if (StrUtil.isNotBlank(attr.getMsgKey())) {
            attr.setMsgKey("00" + attr.getMsgKey());
        }
        List<TopAndLowDto> list = new ArrayList<>();
        list.add(new TopAndLowDto(attr.getOneTopLimit(), attr.getOneLowLimit()));
        list.add(new TopAndLowDto(attr.getTwoTopLimit(), attr.getTwoLowLimit()));
        list.add(new TopAndLowDto(attr.getThreeTopLimit(), attr.getThreeLowLimit()));

        Integer judgeType = attr.getJudgeType();

        if (BizConstant.Range.equals(judgeType)) {
            //不能存在单值
            list.forEach(t -> {
                if (t.ifSingleValueExist()) {
                    throw new RuntimeException("上下限值存在单值！");
                }
            });
            //获取上下都有值的进行判断流程
            List<TopAndLowDto> filterList = list.stream().filter(TopAndLowDto::isAvailable).collect(Collectors.toList());
            if (CollectionUtil.isEmpty(filterList)) {
                log.info("【报警设置保存】=={}", attr);
                throw new RuntimeException("报警设置数值不能为空！");
            }

            //上限判断
            List<Float> topLimitList = filterList.stream().map(TopAndLowDto::getTopLimit).collect(Collectors.toList());
            UpperJudge(topLimitList);
            //下限判断
            List<Float> lowLimitList = filterList.stream().map(TopAndLowDto::getLowLimit).collect(Collectors.toList());
            LowerJudge(lowLimitList);
            //上下限判断
            for (int i = 0; i < filterList.size(); i++) {
                TopAndLowDto topAndLowDto = filterList.get(i);
                if (topAndLowDto.getLowLimit() > topAndLowDto.getTopLimit()) {
                    throw new RuntimeException("下限阈值不能大于上限阈值");
                }
            }
        }

        //上限判断
        if (BizConstant.Upper.equals(judgeType)) {
            List<Float> topLimitList = list.stream().map(TopAndLowDto::getTopLimit).filter(Objects::nonNull).collect(Collectors.toList());
            UpperJudge(topLimitList);
        }

        //下限判断
        if (BizConstant.lower.equals(judgeType)) {
            List<Float> lowLimitList = list.stream().map(TopAndLowDto::getLowLimit).filter(Objects::nonNull).collect(Collectors.toList());
            LowerJudge(lowLimitList);
        }

        UpdateWrapper<DeviceDynamicAttr> uw = new UpdateWrapper<>();
        uw.lambda().eq(DeviceDynamicAttr::getId, attr.getId())
                .set(DeviceDynamicAttr::getOneLowLimit, attr.getOneLowLimit()).set(DeviceDynamicAttr::getOneTopLimit, attr.getOneTopLimit())
                .set(DeviceDynamicAttr::getTwoLowLimit, attr.getTwoLowLimit()).set(DeviceDynamicAttr::getTwoTopLimit, attr.getTwoTopLimit())
                .set(DeviceDynamicAttr::getThreeLowLimit, attr.getThreeLowLimit()).set(DeviceDynamicAttr::getThreeTopLimit, attr.getThreeTopLimit());
//      if (this.update(uw)){
//          this.updateById(attr);
//      }
        this.update(uw);
        return false;
    }
    private void LowerJudge(List<Float> lowLimitList) {
        if (CollectionUtil.isEmpty(lowLimitList)) {
            throw new RuntimeException("报警设置数值不能为空！");
        }
        Float lowTemp = lowLimitList.get(0);
        for (int i = 1; i < lowLimitList.size(); i++) {
            Float nextLowLimit = lowLimitList.get(i);
            if (nextLowLimit > lowTemp) {
                throw new RuntimeException("高级警报下限阈值不能大于低级警报下限阈值");
            }
            lowTemp = nextLowLimit;
        }
    }

    private void UpperJudge(List<Float> topLimitList) {
        if (CollectionUtil.isEmpty(topLimitList)) {
            throw new RuntimeException("报警设置数值不能为空！");
        }

        Float topTemp = topLimitList.get(0);
        for (int i = 1; i < topLimitList.size(); i++) {
            Float nextTopLimit = topLimitList.get(i);
            if (nextTopLimit < topTemp) {
                throw new RuntimeException("高级警报上限阈值不能小于低级警报上限阈值");
            }
            topTemp = nextTopLimit;
        }
    }

    @Override
    public boolean updateAlarmStatus(Long attrId, Integer zero) {
        UpdateWrapper<DeviceDynamicAttr> uw = new UpdateWrapper();
        uw.lambda().eq(DeviceDynamicAttr::getId, attrId).set(DeviceDynamicAttr::getAlarmStatus, BizConstant.ZERO);
        return this.update(uw);
    }

    /**
     * 设备编码和分组编码获取设备动态属性
     *
     * @param deviceCode  设备编码
     * @param alarmFilter 分组编码
     * @return
     */
    @Override
    public List<DeviceDynamicAttr> listAlarmDeviceByDeviceCodeAndAlarmFilter(String deviceCode, String alarmFilter) {
        QueryWrapper<DeviceDynamicAttr> qw = new QueryWrapper<>();
        qw.lambda().eq(DeviceDynamicAttr::getDeviceCode, deviceCode)
                .eq(DeviceDynamicAttr::getIsDel, 0)
                .eq(null != alarmFilter, DeviceDynamicAttr::getAlarmFilter, alarmFilter)
                .eq(DeviceDynamicAttr::getAlarmFlag, 1)
                .select(DeviceDynamicAttr::getId, DeviceDynamicAttr::getDeviceCode, DeviceDynamicAttr::getEngName, DeviceDynamicAttr::getName);
        return deviceDynamicAttrMapper.selectList(qw);
    }

    @Override
    public List<DeviceDynamicAttr> listByDeviceCodeAndJudgeType(String deviceCode, Integer judgeType) {
        QueryWrapper<DeviceDynamicAttr> qw = new QueryWrapper<>();
        qw.eq("device_code", deviceCode)
                .eq("is_del", 0)
                .eq(null != judgeType, "judge_type", judgeType).orderByAsc("name","alarm_filter");
        return deviceDynamicAttrMapper.selectList(qw);
    }


}
